package com.luo.d3s.ext.data.permission.dto.context;

import com.luo.d3s.ext.data.permission.dto.context.base.BaseDpDto;
import com.luo.d3s.ext.data.permission.enums.DpOpEnum;
import com.luo.d3s.ext.data.permission.util.DpUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
import java.util.function.Supplier;

/**
 * 数据权限DTO
 *
 * @author luohq
 * @date 2023-06-20 10:37
 */
public class DpSupplierDto implements BaseDpDto {
    /**
     * 数据权限类型
     */
    private Supplier<String> typeSupplier;

    /**
     * 数据权限支持的操作集合
     */
    private Supplier<Collection<DpOpEnum>> operationsSupplier;

    /**
     * 用户管控的部门或组织（例如用户或者用户角色上关联的管控组织部门ID集合）
     */
    private Supplier<Collection<String>> manageDeptIdsSupplier;

    /**
     * 用户管控的人员（例如用户或者用户角色上关联的管控的人员ID集合）
     */
    private Supplier<Collection<String>> manageUserIdsSupplier;


    public DpSupplierDto() {
    }

    public DpSupplierDto(Supplier<String> typeSupplier, Supplier<Collection<DpOpEnum>> operationsSupplier, Supplier<Collection<?>> manageDeptIdsSupplier, Supplier<Collection<?>> manageUserIdsSupplier) {
        this.setTypeSupplier(typeSupplier);
        this.setOperationsSupplier(operationsSupplier);
        this.setManageDeptIdsSupplier(manageDeptIdsSupplier);
        this.setManageUserIdsSupplier(manageUserIdsSupplier);
    }

    public static DpSupplierDto ofType(Supplier<String> typeSupplier) {
        return new DpSupplierDto(typeSupplier, null, null, null);
    }

    public static DpSupplierDto ofTypeAndOperations(Supplier<String> typeSupplier, Supplier<Collection<DpOpEnum>> operationsSupplier) {
        return new DpSupplierDto(typeSupplier, operationsSupplier, null, null);
    }

    public static DpSupplierDto ofTypeAndManageIds(Supplier<String> typeSupplier, Supplier<Collection<?>> manageDeptIdsSupplier, Supplier<Collection<?>> manageUserIdsSupplier) {
        return new DpSupplierDto(typeSupplier, null, manageDeptIdsSupplier, manageUserIdsSupplier);
    }

    public static DpSupplierDto ofAll(Supplier<String> typeSupplier, Supplier<Collection<DpOpEnum>> operationsSupplier, Supplier<Collection<?>> manageDeptIdsSupplier, Supplier<Collection<?>> manageUserIdsSupplier) {
        return new DpSupplierDto(typeSupplier, operationsSupplier, manageDeptIdsSupplier, manageUserIdsSupplier);
    }

    public static DpSupplierDto fromProp(DpPropDto dpPropDto) {
            if(Objects.isNull(dpPropDto)) {
                return null;
            }
            return new DpSupplierDto(
                    dpPropDto::getType,
                    dpPropDto::getOperations,
                    dpPropDto::getManageDeptIds,
                    dpPropDto::getManageUserIds
            );
    }

    public void setTypeSupplier(Supplier<String> typeSupplier) {
        this.typeSupplier = typeSupplier;
    }

    @Override
    public String getType() {
        return DpUtils.getSupplierValue(this.typeSupplier);
    }


    @Override
    public Collection<DpOpEnum> getOperations() {
        return DpUtils.getSupplierValue(operationsSupplier, Collections.emptySet());
    }

    public void setOperationsSupplier(Supplier<Collection<DpOpEnum>> operationsSupplier) {
        this.operationsSupplier = operationsSupplier;
    }

    public void setManageDeptIdsSupplier(Supplier<Collection<?>> manageDeptIdsSupplier) {
        this.manageDeptIdsSupplier = DpUtils.convertObjToStringCollectionSupplier(manageDeptIdsSupplier);
    }

    @Override
    public Collection<String> getManageDeptIds() {
        return DpUtils.getSupplierValue(this.manageDeptIdsSupplier, Collections.emptySet());
    }

    public void setManageUserIdsSupplier(Supplier<Collection<?>> manageUserIdsSupplier) {
        this.manageUserIdsSupplier = DpUtils.convertObjToStringCollectionSupplier(manageUserIdsSupplier);
    }


    @Override
    public Collection<String> getManageUserIds() {
        return DpUtils.getSupplierValue(this.manageUserIdsSupplier, Collections.emptySet());
    }

    @Override
    public String toString() {
        return "DpSupplierDto{" +
                "typeSupplier=" + typeSupplier +
                ", operationsSupplier=" + operationsSupplier +
                ", manageDeptIdsSupplier=" + manageDeptIdsSupplier +
                ", manageUserIdsSupplier=" + manageUserIdsSupplier +
                '}';
    }
}
